package scheduler;

import java.util.ArrayList;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;

public class LocalWorker implements Runnable{

	private int _nbThread;
	private LinkedBlockingQueue<Task> _queue;
	private ArrayList<Future<Task>> submittedJob;
	private LinkedBlockingQueue<Task> jobsDone;
	
	public LocalWorker(int nbThread, LinkedBlockingQueue<Task> queue, LinkedBlockingQueue<Task> done){
		_nbThread = nbThread;
		_queue = queue;
		submittedJob = new ArrayList<Future<Task>>();
		jobsDone = done;
	}
	
	@Override
	public void run() {
		ExecutorService executorService = Executors.newFixedThreadPool(_nbThread);
		while(true){
			if(!_queue.isEmpty()){
				SleepThread sleepThread = new SleepThread(_queue.poll());
				Future<Task> futur = executorService.submit(sleepThread);
				submittedJob.add(futur);
			}
			for (int i=0; i<submittedJob.size(); i++){
				if (submittedJob.get(i).isDone()){
					try {
						jobsDone.add(submittedJob.get(i).get());
					} catch (InterruptedException e) {
						e.printStackTrace();
					} catch (ExecutionException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	private class SleepThread implements Callable<Task>{

		private Task _task;
		public SleepThread(Task task){
			super();
			_task = task;
		}

		@Override
		public Task call(){
			try {
				Thread.sleep(_task.getTimeToSleep());
				_task.setResult(0);
				return _task;
			} catch (InterruptedException e) {
				_task.setResult(1);
				return _task;
			}
		}	
	}
}
